/*
 *  Copyright 2007 Genoworks
 *  
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *  
 *      http://www.apache.org/licenses/LICENSE-2.0
 *  
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License. 
 */

package com.genoworks.retriever.client;

import java.util.ArrayList;
import java.util.List;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class BaseResult {

  private Integer code = null;

  private String message = null;

  private String value = null;

  private String exception = null;

  private Long processingTime = -1L;

  private List<String> terms = null;

  protected Document resultDoc = null;

  private String rawReply = null;

  private byte[] rawReplyBytes = null;

  private String rawRequest = null;

  protected BaseResult( Document d ) {
    resultDoc = d;

    // code
    final String codeStr = getNodeText( "code" );
    try {
      code = Integer.parseInt( codeStr );
    } catch( Throwable t ) {
      throw new RuntimeException( "Invalid code found. (" + codeStr + ")" );
    }

    // processing time
    final String processingTimeStr = getNodeText( "time" );
    try {
      processingTime = Long.parseLong( processingTimeStr );
    } catch( Throwable t ) {
      throw new RuntimeException( "Invalid processing time found. (" + processingTimeStr
          + ")" );
    }

    // message
    message = getNodeText( "message" );

    // value
    value = getNodeText( "value" );

    // exception
    exception = getNodeText( "exception" );

    // terms
    NodeList termList = resultDoc.getElementsByTagName( "term" );
    if ( termList.getLength() > 0 ) {
      terms = new ArrayList<String>( termList.getLength() );
      final int termLength = termList.getLength();
      for ( int i = 0; i < termLength; i++ ) {
        terms.add( getNodeText( termList.item( i ) ) );
      }
    }
  }

  public final int getCode() {
    return code;
  }

  public final String getMessage() {
    return message;
  }

  public final String getValue() {
    return value;
  }

  public final boolean isError() {
    return getCode() >= 100;
  }

  public final String getException() {
    return exception;
  }

  protected String getNodeText( String tagName ) {
    NodeList nodeList = resultDoc.getElementsByTagName( tagName );
    if ( nodeList.getLength() > 0 ) {
      return getNodeText( nodeList.item( 0 ) );
    }
    return null;
  }

  protected String getNodeText( Node node ) {
    NodeList list = node.getChildNodes();
    final int length = list.getLength();
    for ( int i = 0; i < length; i++ ) {
      Node n = list.item( i );
      if ( n.getNodeType() == Node.CDATA_SECTION_NODE || n.getNodeType() == Node.TEXT_NODE ) {
        return n.getNodeValue();
      }
    }
    return null;
  }

  public final long getProcessingTime() {
    return processingTime;
  }

  public final List<String> getTerms() {
    return terms;
  }

  void setRawReply( String str ) {
    rawReply = str;
  }

  public final String getRawReply() {
    return rawReply;
  }

  void setRawRequest( String str ) {
    rawRequest = str;
  }

  public final String getRawRequest() {
    return rawRequest;
  }

  void setRawReplyBytes( byte[] responseXML ) {
    rawReplyBytes = responseXML;
  }

  public final byte[] getRawReplyBytes() {
    return rawReplyBytes;
  }
}
